#include <wx/msgdlg.h>
#include "CUser.h"
#include "tinyxml.h"
#include "tinystr.h"
#include "Utils.h"


CUser::CUser()
:xmlDoc(NULL)
,next_cursor(0)
{
    //xmlDoc = new DOM();
}

CUser::~CUser()
{
    delete xmlDoc;
    xmlDoc = NULL;
}


/**********************************************
*Remember ! TinyXML can't verify IS_NULL of any returned ptr
*
*We should do it manually if current Node isn't a leaf.
* 'cause there can be cascade "->" , then null->null->null...
*And the app crash.
*
* So NEVER foget it !
***********************************************/
bool CUser::startParsing(const wxString& xmlRawStr)
{
    //assume the input string is always non-null

    /***********************************************************
    * It's kind of weird that if you use the same DOM over and over,
    * the Parse() will append the data, rather than overwrite the previous one
    *
    * Even if you clear the tree , you just clear all the children node,
    * and you can't clear def node <?xml  ?> , then still errors.
    ***********************************************************/
    xmlDoc = new DOM();
    xmlDoc->Parse(xmlRawStr.ToUTF8());
    //#if (defined(XML_DEBUG) || defined(MT_DEBUG_LOG))
        xmlDoc->SaveFile(wxString("rand_")<<rand()<<wxString("_fetched_cursor_")<<next_cursor<<wxString(".xml"));
    //#endif

    Node* root = NULL;
    Node* userNode = NULL;
    user.clear();

    using std::runtime_error;

    try{
        root = xmlDoc->RootElement();
        if(root != NULL)    //root == <users> or <id_list>
        {
            userNode = root->FirstChild();
            if(userNode != NULL)   // userNode == <user> or <ids>
            {
                wxString tag(_T(""));
                wxString textValue(_T(""));
                std::map<wxString , wxString> infoTable;
                Node* infoNode = NULL;

                do
                {
                    if(wxString(userNode->Value()) == wxT("user") || wxString(userNode->Value()) == wxT("ids"))
                    {
                        infoNode = userNode->FirstChild();
                        if(infoNode!=NULL)  //infoNode == <id>
                        {
                            //wxMessageBox(wxString(infoNode->Value()));
                            //wxMessageBox(wxString(infoNode->ToElement()->GetText()));

                            // otherwise , unexpected tag that occurs in one of row will occurs all remaining rows
                            // table structure should be exactly the same as XML
                            infoTable.clear();
                            do
                            {
                                tag = tag.FromUTF8(infoNode->Value());
                                if(tag != wxT("status")) //status is kind of a tree , not a simple map element
                                {
                                    textValue = textValue.FromUTF8(infoNode->ToElement()->GetText());
                                    infoTable[tag] = textValue;
                                    #ifdef XML_DEBUG
                                        wxMessageBox(tag+ " : "+ infoTable[tag]) ;
                                    #endif
                                    #ifdef XML_DEBUG_LOG
                                        LOGMAN.logInfo(tag+ " : "+ infoTable[tag]) ;
                                    #endif
                                }
                                if(wxString(userNode->Value()) == wxT("ids"))
                                {
                                    user.push_back(infoTable);
                                }

                                infoNode = infoNode->NextSibling();
                            }while( infoNode !=NULL );

                            if(wxString(userNode->Value()) == wxT("user"))
                            {
                                user.push_back(infoTable);
                            }



                        }//End of if(inforNode has info)
                        infoNode = NULL;
                    }
                    else if(wxString(userNode->Value()) == _T("next_cursor"))
                    {
                        textValue = textValue.FromUTF8(userNode->ToElement()->GetText());
                        textValue.ToLong(&next_cursor);
                        #ifdef XML_DEBUG
                            wxMessageBox(wxString("inside XML parsing , next_cursor: ")<<next_cursor);
                        #endif
                        #ifdef XML_DEBUG_LOG
                            LOGMAN.logInfo(wxString("inside XML parsing , next_cursor: ")<<next_cursor);
                        #endif
                    }//End of if(is "user")

                    userNode = userNode->NextSibling();
                }while( userNode != NULL );


            }else
            {
                throw runtime_error("set is none");
            }//End of if(userNode)

        }else
        {
            throw runtime_error("XML doc is null");
        }// End of if(root)

    }catch(runtime_error& e)
    {
        #ifdef XML_DEBUG
            wxMessageBox(e.what());
        #endif
        #ifdef XML_LOG
            LOGMAN.logError(e.what());
        #endif

        root = NULL;
        userNode = NULL;
        delete xmlDoc;
        xmlDoc = NULL;
        return false;
    }//End of try

    root = NULL;
    userNode = NULL;
    delete xmlDoc;
    xmlDoc = NULL;
    return true;
}//End of void CUser::startParsing()

tableType& CUser::getUser() throw()
{
    return user;
}
